package cn.ilikes.tools.hbase.jpa.query.pasers;

import java.io.StringReader;
import java.util.List;

import org.slf4j.Logger;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.update.Update;
import cn.ilikes.tools.hbase.jpa.query.iquerys.JPAQuery;
import cn.ilikes.tools.hbase.jpa.query.iquerys.IQuery.SqlType;
import cn.ilikes.tools.hbase.jpa.query.sql.element.GroupBy;
import cn.ilikes.tools.hbase.jpa.query.sql.element.KuTable;
import cn.ilikes.tools.logs.Loggerfactory;

/**
 * select from Table table where table.x = 1
 * 
 * select from Table table where table.x = 1 and table.b =1
 * 
 * select from Table table where table.x = 1 or table.b =1
 * 
 * select table from Table tableA as table where table.x = 1 or table.v.a =1
 * LIMIT 3, 10
 * 
 * 
 * @author fack
 * 
 */
public class DefultIKunderaQueryParser implements IKunderaQueryParser {

	private static Logger logger = Loggerfactory.instance(DefultIKunderaQueryParser.class);

	/** The single-string query string. */
	private String queryString;

	private JPAQuery jpaQuery;

	private PaserWhere paserWhere = new PaserWhere();

	public DefultIKunderaQueryParser(JPAQuery jpaQuery, String sql) {
		this.jpaQuery = jpaQuery;
		this.queryString = sql;

	}

	@Override
	public void parser() throws JPQLParserException {
		if (Loggerfactory.isdebug(logger))
			Loggerfactory.debug(logger, "start paser sql " + queryString);

		CCJSqlParserManager parserManager = new CCJSqlParserManager();
		try {
			Statement state = parserManager.parse(new StringReader(queryString));
			KuTable table = new KuTable();
			jpaQuery.setKuTable(table);
			if (state instanceof Select) {
				jpaQuery.setSqlType(SqlType.select);
				Select select = (Select) state;
				PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
				Table fromItem = (Table) plainSelect.getFromItem();
				table.setTableName(fromItem.getName());
				table.setAliasName(fromItem.getAlias());
				paserOrderBy(plainSelect, table);
				paserWhere.paserWhere(plainSelect.getWhere(), table, false);
			} else if (state instanceof Update) {
				jpaQuery.setSqlType(SqlType.update);
			} else if (state instanceof Delete) {
				jpaQuery.setSqlType(SqlType.delete);
			}
		} catch (JSQLParserException e) {
			throw new JPQLParserException(e);
		}
		if (Loggerfactory.isdebug(logger))
			Loggerfactory.debug(logger, "end  paser sql " + queryString);
	}

	private void paserOrderBy(PlainSelect select, KuTable table) {
		List<?> groupBys = select.getOrderByElements();
		if (groupBys == null)
			return;
		for (Object groupBy_ : groupBys) {
			OrderByElement element = ((OrderByElement) groupBy_);
			Column column = (Column) element.getExpression();
			GroupBy groupBy = new GroupBy();
			groupBy.setGroupType(element.isAsc() ? GroupBy.GroupType.desc : GroupBy.GroupType.asc);
			groupBy.setColumnName(column.getColumnName());
			groupBy.setFullName(column.getWholeColumnName());
			table.getGroupBy().add(groupBy);

		}
	}

}
